package Simulation;

import java.util.Vector;

import mathwork.Mathwork;

import fxana.FxRawDataSet;
import fxana.RawDataCell;

public class ConditionLSMFlag extends ConditionLSM {
	static public Integer default_ref_numberofday=12; 
	static public Double unreached_high_value=10000.0;
	static public Double unreached_low_value=0.0;
	/* This construct is for seed */
	public ConditionLSMFlag(){
		super();
	}
	public ConditionLSMFlag(FxRawDataSet ds, RawDataCell today,
			EvaluatorParaFlag flag) {
		super(ds, today, flag);
	}

	@Override
	protected Condition GetNew(FxRawDataSet ds, RawDataCell today,
			EvaluatorParaFlag flag) {
		return new ConditionLSMFlag(ds,today,flag);
	}

	protected Integer Judge(FxRawDataSet ds, RawDataCell today,
			EvaluatorParaFlag flag){
		int index=ds.GetIndexByDate(today.GetRecDate());
		Vector<Double> histco=new Vector<Double>();
		int i;
		
		/* Get history End-start */
		for(i=0;i<index;i++){
			histco.add(ds.GetRawDataBuffer().elementAt(i).GetEndStart());
		}
		
		/* get the plus and minus*/
		Vector<Double> plus=Mathwork.plusminus(histco).elementAt(0);
		Vector<Double> minus=Mathwork.plusminus(histco).elementAt(1);
		
		/* about yesterday */
		Double yesterday=Mathwork.lastplusminus(histco);
		if(yesterday.compareTo(0.0)>=0){
			/* yesterday is plus */
			Double oklimit=Mathwork.lognormalest(plus, 0.70).elementAt(0);
			if(yesterday.compareTo(oklimit)>=0){
				/* dangerous */
				Double invlimit=Mathwork.lognormalest(plus, 0.85).elementAt(0);
				if(yesterday.compareTo(invlimit)>=0){
					return 1; /* only sell*/
				}else{
					/*oklimit~inlimit*/
					return -1; /* don't oder new one, but should deal with old one */
				}
			}else{
				/* ok ,today can order with double */
				return 0; /* both buy and sell */
			}
		}else{
			/* yesterday is minus */
			Double oklimit=Mathwork.lognormalest(minus, 0.70).elementAt(0);
			/* because yesterday < 0 so do abs */
			if(new Double(Math.abs(yesterday)).compareTo(oklimit)>=0){
				/* dangerous */
				Double invlimit=Mathwork.lognormalest(minus, 0.85).elementAt(0);
				if(yesterday.compareTo(invlimit)>=0){
					return 2; /* only buy */
				}else{
					/*oklimit~inlimit*/
					return -1; /* don't oder new one, but should deal with old one */
				}
			}else{
				/* ok ,today can order with double */
				return 0; /* both buy and sell */
			}
		}
	}
	
	@Override
	protected RawDataCell GetEstimatedValue(FxRawDataSet ds, RawDataCell today,
			EvaluatorParaFlag flag) {
		Integer numberofday=25;
		
		if(flag.IsMFlagSet()&&flag.GetMFlagIterator().hasNext()){
			numberofday=flag.GetMFlagIterator().next();
		}
		
		RawDataCell est=ds.GetLSMDataByDate(today.GetRecDate(), numberofday);
		if(est==null){
			return null;
		}
		if(this.State==ConditionState.NULL){
			switch(this.Judge(ds, today, flag)){
			case 0:/*both buy and sell*/
					return est;
			case 1:/*only sell*/
					return new RawDataCell(today.GetFSRecDate(),today.GetStartValue(),
						est.GetHighValue(),ConditionLSMFlag.unreached_low_value,est.GetEndValue());
			case 2:/*only buy*/
					return new RawDataCell(today.GetFSRecDate(),today.GetStartValue(),
						ConditionLSMFlag.unreached_high_value,est.GetLowValue(),est.GetEndValue());
			default: /* no buy and no sell*/
				return new RawDataCell(today.GetFSRecDate(),today.GetStartValue(),
						ConditionLSMFlag.unreached_high_value,ConditionLSMFlag.unreached_low_value,est.GetEndValue());
			}
		}
		
		return est;
	}
	
}
